import { Card, Divider, Form, Input, Select, Row, Col, Collapse, Button, Dropdown, Menu, Checkbox, message } from "antd";
import { PlusOutlined, MinusOutlined, CaretRightOutlined } from "@ant-design/icons";
import React, { useContext, useEffect, useState } from "react";
import "./api.less";
import { useForm } from "antd/lib/form/Form";
import { FormContext } from "./context";
import { apiGet, apiMod } from "../vo/request";

const { Option } = Select;
const { Panel } = Collapse;
const { TextArea } = Input;

let forms = {
    initValue: {},
    get: {
        getBaseFormdata: (): any => { },
        getRequestHeaderFormdata: (): any => { },
        getQueryFormdata: (): any => { },
        getRequestBodyFormdata: (): any => { },
        getResponseHeaderFormData: (): any => { },
        getResponseBodyFormdata: (): any => { }
    },
}

export function ApiPage(props: { dataKey: any }) {
    const [formsData, setFormsData] = useState({
        apiId: "",
        apiName: "",
        groupId: "",
        apiMethod: "GET",
        apiPath: "",
        apiStatus: "",
        description: "",
        requestHeader: [{ key: "", value: "" }],
        responseHeader: [{ key: "", value: "" }],
        query: [{ key: "", value: "" }],
        requestBody: {
            type: "json",
            nodes: [{
                name: "",
                value: "",
                type: "string",
                note: "",
                must: true,
                lv: 1
            }]
        } as any,
        responseBody: {
            type: "json",
            nodes: [{
                name: "",
                value: "",
                type: "string",
                note: "",
                must: true,
                lv: 1
            }]
        } as any
    } as any);
    const [isSaving, setSaving] = useState(false);
    const { dataKey } = props;
    useEffect(() => {
        if (dataKey.substring(3) !== "" + formsData.apiId) {
            (async () => {
                try {
                    if (dataKey !== "allapi") {
                        let id = dataKey.substring(3);
                        setSaving(true);
                        let res = await apiGet.getApiInformationById(parseInt(id));

                        if (!res.code && res.data) {
                            setSaving(false);
                            let data = toggleData(res.data);
                            setFormsData(data);
                        } else {
                            message.error(res.msg);
                        }
                    }
                } catch (err) {
                    console.log(err);
                    message.error('未知错误,见控制台');
                }
            })();
        }
    }, [dataKey, formsData.apiId])


    const clickSave = async () => {
        let newData = {
            apiId: formsData.apiId,
            apiBaseUrl: forms.get.getBaseFormdata().baseUrl,
            apiName: forms.get.getBaseFormdata().name,
            folderId: forms.get.getBaseFormdata().groupId,
            apiMethod: forms.get.getBaseFormdata().method,
            apiPath: forms.get.getBaseFormdata().apipath,
            apiStatus: forms.get.getBaseFormdata().status,
            description: forms.get.getBaseFormdata().description,
            requestHeader: JSON.stringify(forms.get.getRequestHeaderFormdata().reqheaders),
            responseHeader: JSON.stringify(forms.get.getResponseHeaderFormData().resheaders),
            query: JSON.stringify(forms.get.getQueryFormdata().querys),
            requestBody: forms.get.getRequestBodyFormdata(),
            responseBody: forms.get.getResponseBodyFormdata()
        }
        console.log(newData);
        try {
            setSaving(true);
            let res = await apiMod.update(newData);
            setSaving(false);
            if (!res.code && res.data) {
                message.success("保存成功");
            } else {
                message.error(res.msg);
            }
        } catch (err) {
            console.log(err);
            message.error("未知错误，详情见控制台");
            setSaving(false);
        }
    }
    return (
        <FormContext.Provider value={formsData}>
            <BasicInformation />
            <ParamInformation />
            <div className="save-strick">
                <Button onClick={clickSave} loading={isSaving}>保存</Button>
            </div>

        </FormContext.Provider>
    )
}

function toggleData(data: any): any {
    console.log(data);
    data.requestBody.type = data.requestBody.type ? data.requestBody.type : "json";
    data.requestBody.nodes = data.requestBody.nodes.length ? data.requestBody.nodes : [{
        name: "",
        value: "",
        type: "string",
        note: "",
        must: true,
        lv: 1
    }];
    data.responseBody.type = data.responseBody.type ? data.responseBody.type : "json";
    data.responseBody.nodes = data.responseBody.nodes.length ? data.responseBody.nodes : [{
        name: "",
        value: "",
        type: "string",
        note: "",
        must: true,
        lv: 1
    }];
    let rtn = {
        apiPath: data.apiPath,
        apiId: data.apiId,
        apiBaseUrl: data.apiBaseUrl,
        apiMethod: data.apiMethod,
        apiName: data.apiName,
        apiStatus: data.apiStatus,
        description: data.description,
        folderId: data.folderId,
        query: data.query? JSON.parse(data.query) : [{ key: "", value: "", note: "" }],
        requestHeader: data.requestHeader ? JSON.parse(data.requestHeader) : [{ key: "", value: "", note: "" }],
        responseHeader: data.responseHeader ? JSON.parse(data.responseHeader) : [{ key: "", value: "", note: "" }],
        responseBody: data.responseBody,
        requestBody: data.requestBody
    }

    return rtn;
}

// function compareStringObject(obj1: any, obj2: any) {
//     if (obj1 === undefined) {
//         obj1 = { key: "", value: "" }

//     }
//     if (obj2 === undefined) {
//         obj2 = { key: "", value: "" }
//     }
//     for (let key in obj1) {
//         if (obj1[key] !== obj2[key]) {
//             return false;
//         }
//     }
//     return true;
// }

// function compareFormsData(oldData: any, newData: any) {
//     const baseSet = new Set(["apiName", "apiMethod", "apiId", "apiPath", "apiStatus", "description"]);
//     const objArrSet = new Set(["requestHeader", "responseHeader", "query"]);
//     const treeSet = new Set(["responseBody", "requestbody"]);
//     const notMod = new Set(["groupId"])
//     for (let key in oldData) {
//         if (baseSet.has(key)) {
//             if (oldData[key] !== newData[key]) {
//                 return false;
//             }
//         } else if (objArrSet.has(key)) {
//             let temp: any[] = [];
//             newData[key].forEach((value: any) => {
//                 if (value && (value.key || value.value)) {
//                     temp.push(value);
//                 }
//             });
//             if (temp.length === 0) {
//                 temp.push({ key: "", value: "" })
//             }
//             newData[key] = temp;
//             if (newData[key].length !== oldData[key].length) {
//                 return false
//             } else {
//                 let flag = true;
//                 for (let i = 0; i < newData[key].length; i++) {
//                     if (!compareStringObject(oldData[key][i], newData[key][i])) {
//                         flag = false;
//                         break;
//                     }
//                 }
//                 if (!flag) {
//                     return false;
//                 }
//             }
//         } else if (treeSet.has(key)) {
//             if (newData[key].type !== oldData[key].type) {
//                 return false;
//             }
//             if (!oldData[key]) {
//                 return false;
//             }
//             if (newData[key].nodes.length !== oldData[key].nodes.length) {
//                 return false;
//             } else {
//                 for (let i = 0; i < newData[key].nodes.length; i++) {
//                     if (!compareStringObject(newData[key].nodes[i], oldData[key].nodes[i])) {
//                         return false
//                     }
//                 }
//             }
//         } else if (notMod.has(key)) {
//             continue;
//         }
//     }
//     return true;
// }


function BasicInformation() {
    const formsData = useContext(FormContext);
    const [form] = useForm();
    useEffect(() => {
        forms.get.getBaseFormdata = () => {
            return form.getFieldsValue();
        };
        form.setFieldsValue({
            method: formsData.apiMethod,
            name: formsData.apiName,
            apipath: formsData.apiPath,
            status: formsData.apiStatus,
            description: formsData.description,
            groupId: formsData.folderId
        })
    }, [form, formsData]);

    const methodSelector = (
        <Form.Item name="method" noStyle>
            <Select style={{ width: 90 }}>
                <Option value="GET">GET</Option>
                <Option value="POST">POST</Option>
            </Select>
        </Form.Item>
    )
    const layout = {
        labelCol: { span: 3 },
        wrapperCol: { span: 10 },
    };
    return (
        <Card title="基础信息">
            <Form
                form={form}
                {...layout}
                initialValues={{
                    method: formsData.apiMethod,
                    name: formsData.apiName,
                    apipath: formsData.apiPath,
                    status: formsData.apiStatus,
                }}
                name="basic"
            >
                <Form.Item label="接口名称" name="name">
                    <Input></Input>
                </Form.Item>
                <Form.Item label="BaseUrl" name="baseurl">
                    <Input></Input>
                </Form.Item>
                <Form.Item label="接口路径" name="apipath">
                    <Input addonBefore={methodSelector} ></Input>
                </Form.Item>
                <Form.Item label="状态" name="status">
                    <Select>
                        <Option value="finish">已完成</Option>
                        <Option value="creating">开发中</Option>
                    </Select>
                </Form.Item>
                <Form.Item label="描述" name="description">
                    <TextArea autoSize={{ minRows: 2 }}></TextArea>
                </Form.Item>
                <div style={{ display: "none" }}>
                    <Form.Item label="" name="groupId" >
                        <Input></Input>
                    </Form.Item>
                </div>

            </Form>
        </Card>
    )
}

function ParamInformation() {

    return (
        <Card title="参数设置">
            <RequestHeaderInformition />
            <Divider></Divider>
            <QueryParamInformition />
            <Divider></Divider>
            <RequestBody />
            <Divider></Divider>
            <ResponseHeaderInformition />
            <Divider></Divider>
            < ResponseBody />
        </Card>
    )
}

function ResponseBody() {
    const formsData = useContext(FormContext);
    const [nodes, setNodes] = useState(formsData.responseBody.nodes);
    const [type, setType] = useState(formsData.responseBody.type);
    forms.get.getResponseBodyFormdata = () => {
        return {
            type: type,
            nodes: nodes
        }
    }
    useEffect(() => {
        setNodes(formsData.responseBody.nodes);
        setType(formsData.responseBody.type);
    }, [formsData]);
    const MOD = {
        onTypeChanged: (v: string, index: number) => {
            nodes[index].type = v;
            let i = index + 1;
            while (i <= nodes.length - 1) {
                if (nodes[i].lv > nodes[index].lv) {
                    nodes.splice(i, 1);
                } else {
                    break;
                }
            }
            setNodes(nodes.slice(0));
        },
        addChild: (index: number) => {
            let i = index + 1;
            while (i <= nodes.length - 1 && nodes[i].lv - nodes[index].lv === 1) {
                i++;
            }
            nodes.splice(i, 0, {
                lv: nodes[index].lv + 1,
                name: "",
                value: "",
                type: "string",
                note: "",
                must: false
            });
            setNodes(nodes.slice(0));
        },
        addBrother: (index: number) => {
            let i = index + 1;
            while (i <= nodes.length - 1 && nodes[i].lv >= nodes[index].lv) {
                i++;
            }
            nodes.splice(i, 0, {
                lv: nodes[index].lv,
                name: "",
                value: "",
                type: "string",
                note: "",
                must: false
            });
            setNodes(nodes.slice(0));
        },
        onDelete: (index: number) => {
            let i = index + 1;
            while (i <= nodes.length - 1) {
                if (nodes[i].lv > nodes[index].lv) {
                    nodes.splice(i, 1);
                } else {
                    break;
                }
            }
            nodes.splice(index, 1);
            setNodes(nodes.slice(0));
        },
        onValueChange(v: any, n: string, index: number) {
            (nodes[index] as any)[n] = v;
            setNodes(nodes.slice(0));
        }
    }
    return (
        <>
            <Collapse
                bordered={false}
                style={{
                    backgroundColor: "#fff"
                }}
                defaultActiveKey={"1"}
            >
                <Panel header="响应体" key="1" style={{ border: "none" }}>
                    {setBodyForm(nodes, "response", MOD, type)}
                </Panel>
            </Collapse>
        </>
    )
}

function RequestBody() {
    const formsData = useContext(FormContext);
    const [nodes, setNodes] = useState(formsData.requestBody.nodes);
    const [type, setType] = useState(formsData.requestBody.type);
    forms.get.getRequestBodyFormdata = () => {
        return {
            type: type,
            nodes: nodes
        }
    }
    useEffect(() => {
        setNodes(formsData.requestBody.nodes);
        setType(formsData.requestBody.type);
    }, [formsData]);

    const MOD = {
        onTypeChanged: (v: string, index: number) => {
            nodes[index].type = v;
            let i = index + 1;
            while (i <= nodes.length - 1) {
                if (nodes[i].lv > nodes[index].lv) {
                    nodes.splice(i, 1);
                } else {
                    break;
                }
            }
            setNodes(nodes.slice(0));
        },
        addChild: (index: number) => {
            let i = index + 1;
            while (i <= nodes.length - 1 && nodes[i].lv - nodes[index].lv === 1) {
                i++;
            }
            nodes.splice(i, 0, {
                lv: nodes[index].lv + 1,
                name: "",
                value: "",
                type: "string",
                note: "",
                must: false
            });
            setNodes(nodes.slice(0));
        },
        addBrother: (index: number) => {
            let i = index + 1;
            while (i <= nodes.length - 1 && nodes[i].lv >= nodes[index].lv) {
                i++;
            }
            nodes.splice(i, 0, {
                lv: nodes[index].lv,
                name: "",
                value: "",
                type: "string",
                note: "",
                must: false
            });
            setNodes(nodes.slice(0));
        },
        onDelete: (index: number) => {
            let i = index + 1;
            while (i <= nodes.length - 1) {
                if (nodes[i].lv > nodes[index].lv) {
                    nodes.splice(i, 1);
                } else {
                    break;
                }
            }
            nodes.splice(index, 1);
            setNodes(nodes.slice(0));
        },
        onValueChange(v: any, n: string, index: number) {
            (nodes[index] as any)[n] = v;
            setNodes(nodes.slice(0));
        }

    }
    return (
        <>
            <Collapse
                bordered={false}
                style={{
                    backgroundColor: "#fff"
                }}
                defaultActiveKey={"1"}
            >
                <Panel header="请求体" key="1" style={{ border: "none" }}>
                    <Form style={{ marginLeft: 30 }} wrapperCol={{ span: 4 }}>
                        <Form.Item label="数据格式">
                            <Select value={type} onChange={(v) => { setType(v as string); setNodes([{ lv: 1, name: "", value: "", type: "string", must: true, note: "" }]) }}>
                                <Option value="json">JSON</Option>
                                <Option value="formdata">FormData</Option>
                            </Select>
                        </Form.Item>
                    </Form>
                    {setBodyForm(nodes, "request", MOD, type)}
                </Panel>
            </Collapse>
        </>
    )
}

type FORMMOD = {
    onTypeChanged: (v: string, index: number) => void;
    addChild: (index: number) => void;
    addBrother: (index: number) => void;
    onDelete: (index: number) => void;
    onValueChange: (v: any, n: string, index: number) => void
}

function setBodyForm(nodes: any[], name: string, MOD: FORMMOD, type: string): React.ReactElement[] {
    let arr: React.ReactElement[] = [];
    let stack: { node: any, children: React.ReactElement[], index: number, fatherType: string }[] = [];
    let father = "object";
    nodes.forEach((node, index) => {
        if (index === 0 || node.lv >= stack[stack.length - 1].node.lv) {
            if (index !== 0 && node.lv > stack[stack.length - 1].node.lv) {
                father = stack[stack.length - 1].node.type;
            }
            stack.push({
                node: node,
                children: [],
                index: index,
                fatherType: father
            });
        } else {
            let nodeArr: React.ReactElement[] = [];
            let prev = 0;
            while (true) {
                let temp = stack.pop() as {
                    node: any;
                    children: React.ReactElement[];
                    index: number;
                    fatherType: string
                };
                let disables = [];
                if (temp.node.type === "object") {
                    disables.push("value");
                }
                if (temp.fatherType === "array") {
                    disables.push("name");
                }
                if (temp?.node.lv === node.lv) {
                    temp.children = nodeArr.reverse();
                    stack.push(temp);
                    stack.push({
                        node: node,
                        children: [],
                        index: index,
                        fatherType: temp.fatherType
                    });
                    break;
                } else {
                    if (prev) {
                        if (prev === temp.node.lv) {
                            prev = temp.node.lv;
                            if (temp.children.length) {
                                nodeArr.push(
                                    <Folder
                                        disables={disables}
                                        key={name + temp.index}
                                        index={"" + temp.index}
                                        data={temp.node}
                                        open={true}
                                        type={temp.node.type}
                                        MOD={MOD}
                                        name={name}
                                        dataType={type}
                                    >
                                        {temp.children}
                                    </Folder>
                                );
                            } else {
                                nodeArr.push(
                                    <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD} />
                                );
                            }
                        } else {
                            prev = temp.node.lv;
                            temp.children = nodeArr.reverse();
                            stack.push(temp);
                            nodeArr = [];
                        }
                    } else {
                        prev = temp.node.lv;
                        if (temp.children.length) {
                            nodeArr.push(
                                <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD}>
                                    {temp.children}
                                </Folder>
                            );
                        } else {
                            nodeArr.push(
                                <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD} />
                            );
                        }
                    }
                }
            }
        }
    });

    let nodeArr: React.ReactElement[] = [];
    let prev = 0;
    while (true) {
        let temp = stack.pop() as {
            node: any;
            children: React.ReactElement[];
            index: number;
            fatherType: string
        };
        let disables = [];
        if (temp.node.type === "object") {
            disables.push("value");
        }
        if (temp.fatherType === "array") {
            disables.push("name");
        }
        if (stack.length === 0) {
            if (temp.node.lv < prev) {

                arr.push(
                    <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD}>
                        {nodeArr.reverse()}
                    </Folder>
                )
                break;
            } else {
                if (temp.children.length) {
                    nodeArr.push(
                        <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD}>
                            {temp.children}
                        </Folder>
                    );
                } else {
                    nodeArr.push(
                        <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD} />
                    );
                }
                arr = nodeArr;
                break;
            }
        } else {
            if (prev) {
                if (prev === temp.node.lv) {
                    prev = temp.node.lv;
                    if (temp.children.length) {
                        nodeArr.push(
                            <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD}>
                                {temp.children}
                            </Folder>
                        );
                    } else {
                        nodeArr.push(
                            <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD} />
                        );
                    }
                } else {
                    prev = temp.node.lv;
                    temp.children = nodeArr.reverse();
                    stack.push(temp);
                    nodeArr = [];
                }
            } else {
                prev = temp.node.lv;
                if (temp.children.length) {
                    nodeArr.push(
                        <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD}>
                            {temp.children}
                        </Folder>
                    );
                } else {
                    nodeArr.push(
                        <Folder disables={disables} dataType={type} name={name} key={name + temp.index} index={"" + temp.index} data={temp.node} open={true} type={temp.node.type} MOD={MOD} />
                    );
                }
            }
        }
    }
    return arr.reverse();
}

function RequestHeaderInformition() {
    const [form] = useForm();
    const formsData = useContext(FormContext);
    forms.get.getRequestHeaderFormdata = () => {
        return form.getFieldsValue();
    };
    useEffect(() => {
        form.setFieldsValue({
            reqheaders: formsData.requestHeader
        })
    }, [formsData, form])
    return (
        <Collapse
            bordered={false}
            style={{
                backgroundColor: "#fff"
            }}
            defaultActiveKey={"1"}
        >
            <Panel header="请求头" key="1" style={{ border: "none" }}>
                <div style={{
                    marginTop: 10
                }}>
                    <Row gutter={[40, 16]}>
                        <Form form={form} name="reqeader" autoComplete="off" style={{ width: "100%" }}>
                            <Form.List
                                name="reqheaders"
                            >
                                {(fields, { add, remove }) => {
                                    return (

                                        <>
                                            {fields.map(({ key, name, fieldKey, ...restField }, index) => (
                                                <Row align="middle" key={key} style={{ display: 'flex', marginBottom: 8 }} gutter={20}>
                                                    <Col offset={1} span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'key']}
                                                            fieldKey={[fieldKey, 'key']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="字段名" />
                                                        </Form.Item>
                                                    </Col>
                                                    <Col span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'value']}
                                                            fieldKey={[fieldKey, 'value']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="字段值" />
                                                        </Form.Item>
                                                    </Col>
                                                    <Col span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'note']}
                                                            fieldKey={[fieldKey, 'note']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="备注" />
                                                        </Form.Item>
                                                    </Col>

                                                    <Button type="link" size="small" onClick={() => { add() }}><PlusOutlined /></Button>
                                                    {index >= 1 ? <Button type="link" size="small" onClick={() => remove(name)}><MinusOutlined /></Button> : ""}
                                                </Row>

                                            ))}
                                        </>
                                    )
                                }}
                            </Form.List>
                        </Form>
                    </Row>
                </div>
            </Panel>
        </Collapse>
    )
}

function QueryParamInformition() {
    const [form] = useForm();
    const formsData = useContext(FormContext);
    forms.get.getQueryFormdata = () => {
        return form.getFieldsValue();
    }
    useEffect(() => {
        form.setFieldsValue({
            querys: formsData.query
        })
    }, [formsData, form])
    return (
        <Collapse
            bordered={false}
            style={{
                backgroundColor: "#fff"
            }}
            defaultActiveKey={"1"}
        >
            <Panel header="Query" key="1" style={{ border: "none" }}>
                <div style={{
                    marginTop: 10
                }}>
                    <Row gutter={[40, 16]}>
                        <Form name="query" form={form} autoComplete="off" style={{ width: "100%" }}>
                            <Form.List
                                name="querys"
                            >
                                {(fields, { add, remove }) => {
                                    return (

                                        <>
                                            {fields.map(({ key, name, fieldKey, ...restField }, index) => (
                                                <Row align="middle" key={key} style={{ display: 'flex', marginBottom: 8 }} gutter={20}>
                                                    <Col offset={1} span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'key']}
                                                            fieldKey={[fieldKey, 'key']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="字段名" />
                                                        </Form.Item>
                                                    </Col>
                                                    <Col span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'value']}
                                                            fieldKey={[fieldKey, 'value']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="字段值" />
                                                        </Form.Item>
                                                    </Col>
                                                    <Col span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'note']}
                                                            fieldKey={[fieldKey, 'note']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="备注" />
                                                        </Form.Item>
                                                    </Col>
                                                    <Button type="link" size="small" onClick={() => { add() }}><PlusOutlined /></Button>
                                                    {index >= 1 ? <Button type="link" size="small" onClick={() => remove(name)}><MinusOutlined /></Button> : ""}
                                                </Row>

                                            ))}
                                        </>
                                    )
                                }}
                            </Form.List>
                        </Form>
                    </Row>
                </div>
            </Panel>
        </Collapse>
    )
}


function ResponseHeaderInformition() {
    const formsData = useContext(FormContext);
    const [form] = useForm();
    const onFinish = (values: any) => {
        console.log('Received values of form:', values);
    };
    forms.get.getResponseHeaderFormData = () => {
        return form.getFieldsValue();
    }
    useEffect(() => {
        form.setFieldsValue({
            resheaders: formsData.responseHeader
        })
    }, [formsData, form])
    return (
        <Collapse
            bordered={false}
            style={{
                backgroundColor: "#fff"
            }}
            defaultActiveKey={"1"}
        >
            <Panel header="响应头" key="1" style={{ border: "none" }}>
                <div style={{
                    marginTop: 10
                }}>
                    <Row gutter={[40, 16]}>
                        <Form form={form} name="resheader" onFinish={onFinish} autoComplete="off" style={{ width: "100%" }}>
                            <Form.List
                                name="resheaders"
                                initialValue={formsData.responseHeader}
                            >
                                {(fields, { add, remove }) => {
                                    return (

                                        <>
                                            {fields.map(({ key, name, fieldKey, ...restField }, index) => (
                                                <Row align="middle" key={key} style={{ display: 'flex', marginBottom: 8 }} gutter={20}>
                                                    <Col offset={1} span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'key']}
                                                            fieldKey={[fieldKey, 'key']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="字段名" />
                                                        </Form.Item>
                                                    </Col>
                                                    <Col span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'value']}
                                                            fieldKey={[fieldKey, 'value']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="字段值" />
                                                        </Form.Item>
                                                    </Col>
                                                    <Col span={6}>
                                                        <Form.Item
                                                            {...restField}
                                                            name={[name, 'note']}
                                                            fieldKey={[fieldKey, 'note']}
                                                            noStyle
                                                        >
                                                            <Input placeholder="备注" />
                                                        </Form.Item>
                                                    </Col>

                                                    <Button type="link" size="small" onClick={() => { add() }}><PlusOutlined /></Button>
                                                    {index >= 1 ? <Button type="link" size="small" onClick={() => remove(name)}><MinusOutlined /></Button> : ""}
                                                </Row>

                                            ))}
                                        </>
                                    )
                                }}
                            </Form.List>
                        </Form>
                    </Row>
                </div>
            </Panel>
        </Collapse>
    )
}


type Folderprops = {
    children?: React.ReactElement | React.ReactElement[];
    open?: boolean;
    type?: string;
    data?: any;
    index?: string;
    MOD?: FORMMOD;
    name: string;
    dataType: string;
    disables?: string[]
}

function Folder(props: Folderprops) {
    const { children, open, type, data, index, MOD, name, disables } = props;
    let disableSet: Set<string>;
    if (disables) {
        disableSet = new Set(disables);
    } else {
        disableSet = new Set();
    }
    const [isOpen, setOpen] = useState(open);
    const [form] = useForm();
    let isFolder: boolean = type === "object" || type === "array";
    const toggleOpen = () => {
        if (isFolder) {
            setOpen((isOpen) => {
                return !isOpen
            });
        }
    }
    useEffect(() => {
        form.setFieldsValue(data);
    }, [data, form]);
    const menu = (
        <Menu>
            <Menu.Item key={name + (index as string) + "b"}>
                <div onClick={() => { MOD?.addBrother(parseInt(index as string)) }}>兄弟结点</div>
            </Menu.Item>
            <Menu.Item key={name + (index as string) + "c"}>
                <div onClick={() => { MOD?.addChild(parseInt(index as string)) }}>子结点</div>
            </Menu.Item>
        </Menu>
    )

    return (
        <>
            <Form name={name + "_" + index} form={form} style={{ margin: "5px 0" }}>
                <Row gutter={20} align="middle">
                    <Col span={7}>
                        <div style={{ display: "flex", alignItems: "center", paddingLeft: (data.lv - 1) * 20 }}>
                            <Button type="link" size="small" onClick={toggleOpen}>
                                <CaretRightOutlined className={`openicon ${isOpen ? "open" : ""}`} style={{ opacity: isFolder ? 1 : 0 }} />
                            </Button>
                            <Form.Item
                                name={"name"}
                                noStyle
                                style={{ flexGrow: 1 }}
                            >
                                <Input disabled={disableSet.has("name")} onBlur={(e) => { MOD?.onValueChange(e.target.value, "name", parseInt(index as string)) }} placeholder="字段名称"></Input>
                            </Form.Item>
                        </div>
                    </Col>
                    <Col span={4}>
                        <Form.Item
                            name={"type"}
                            noStyle
                        >
                            <Select
                                disabled={disableSet.has("type")}
                                placeholder="数据类型"
                                style={{ width: "100%" }}
                                onChange={(v) => { console.log(v); MOD?.onTypeChanged(v as string, parseInt(index as string)) }}
                            >
                                {props.dataType === "json" ? <>
                                    <Option value="string">String</Option>
                                    <Option value="number">Number</Option>
                                    <Option value="boolean">Boolean</Option>
                                    <Option value="array">Array</Option>
                                    <Option value="object">Object</Option>
                                </> :
                                    <>
                                        <Option value="string">String</Option>
                                        <Option value="file">File</Option>
                                    </>
                                }

                            </Select>
                        </Form.Item>
                    </Col>
                    <Col span={2}>
                        <Form.Item
                            name={"must"}
                            noStyle
                        >
                            <Checkbox
                                disabled={disableSet.has("must")}
                                onChange={(e) => { MOD?.onValueChange(e.target.checked, "must", parseInt(index as string)) }}
                                style={{ textOverflow: "ellipsis", whiteSpace: "nowrap", overflow: "hidden" }}
                                checked={data.must}>
                                必有
                            </Checkbox>
                        </Form.Item>
                    </Col>
                    <Col span={4}>
                        <Form.Item
                            name={"value"}
                            noStyle
                        >
                            <Input disabled={disableSet.has("value")} onBlur={(e) => { MOD?.onValueChange(e.target.value, "value", parseInt(index as string)) }} placeholder="字段值"></Input>
                        </Form.Item>
                    </Col>
                    <Col span={5}>
                        <Form.Item
                            name={"note"}
                            noStyle
                        >
                            <Input disabled={disableSet.has("note")} onBlur={(e) => { MOD?.onValueChange(e.target.value, "note", parseInt(index as string)) }} placeholder="备注"></Input>
                        </Form.Item>
                    </Col>
                    <Col span={2} style={{ display: "flex", flexWrap: "nowrap" }}>
                        {
                            type === "object" || type === "array"
                                ? <Dropdown overlay={menu}>
                                    <Button size="small" type="link"><PlusOutlined /></Button>
                                </Dropdown>
                                : <Button onClick={() => { MOD?.addBrother(parseInt(index as string)) }} size="small" type="link"><PlusOutlined /></Button>
                        }
                        {index === "0" ? "" : <Button onClick={() => { MOD?.onDelete(parseInt(index as string)) }} size="small" type="link"><MinusOutlined /></Button>}

                    </Col>
                </Row>
            </Form>
            <div
                className={`folder-children ${isOpen ? "open" : ""}`}
            >
                {isFolder && children ? children : ""}
            </div>
        </>
    )
}